﻿using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Having.Site.DataCache.Sysnet
{
    public class SysnetPool : IDataCacheHelper
    {
        private static SysnetPool _SysnetPool=null;
        static readonly object Sysnetlock = new object();
        static readonly object setlock = new object();
        public int cachedefaults = 0;
        static List<string> keys = new List<string>();
        static MemoryCache _memoryCache = new MemoryCache(new MemoryCacheOptions());
        public static SysnetPool GetPool( int _cachedefaults = 20)
        {
            if (_SysnetPool == null)
            {
                lock (Sysnetlock)
                {
                    _SysnetPool = new SysnetPool(_cachedefaults);
                }
            }
            return _SysnetPool;
        }
        public SysnetPool(int _cachedefaults=20)
        {
            cachedefaults = _cachedefaults;
        }
        public T Get<T>(string key)
        {
            string val = null;
            var isok = _memoryCache.TryGetValue(key, out val);
            if (!string.IsNullOrWhiteSpace(val))
            {
                return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(val);
            }
            else
            {
                return default(T);
            }
        }

        public bool HasKey(string key)
        {
            string val = null;
            var isok = _memoryCache.TryGetValue(key, out val);
            return isok ? !string.IsNullOrWhiteSpace(val) : false;
        }

        public void Remove(string key)
        {
            _memoryCache.Remove(key);
            keys.Remove(key);
        }

        public void Set<T>(string key, T value, int ss = 0,bool islock=false)
        {
            if (ss == 0) { ss = cachedefaults; }
            if (islock)
            {
                lock (setlock)
                {
                    Set(key, (object)value, ss);
                }
            }
            else
            {
                Set(key, (object)value, ss);
            }

        }

        private void Set(string key, object value, int ss = 0)
        {
            if (ss < 0)
            {
                _memoryCache.Set(key, Newtonsoft.Json.JsonConvert.SerializeObject(value));
                keys.Add(key);
            }
            else
            {
                if (ss > 0)
                {
                    _memoryCache.Set(key, Newtonsoft.Json.JsonConvert.SerializeObject(value), new MemoryCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(ss)).RegisterPostEvictionCallback((keyitem, valueitem, reason, substate) =>
                    {
                        keys.Remove(key);
                    }));
                    keys.Add(key);
                }
            }
        }

        public void Clear()
        {
            foreach (var item in keys)
            {
                _memoryCache.Remove(item);
            }
        }

        public void RemoveLike(string regex)
        {
            var pl = keys.Where(m => m.IndexOf(regex) > -1).ToList();
            foreach (var item in pl)
            {
                Remove(item);
            }
        }
    }
}
